# 密码管理路由
from flask import Blueprint, render_template, request, jsonify, session, redirect, url_for
from models import db
from models.password import Password, MasterPassword
from services.crypto_service import CryptoService
from functools import wraps

password_bp = Blueprint('password', __name__, url_prefix='/password')

def master_password_required(f):
    """装饰器：要求已验证主密码"""
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if 'master_password' not in session:
            return jsonify({'error': '请先验证主密码'}), 401
        return f(*args, **kwargs)
    return decorated_function

@password_bp.route('/')
def list_passwords():
    """显示密码管理页面"""
    return render_template('password.html')

@password_bp.route('/api/check-master', methods=['GET'])
def check_master_password():
    """检查是否已设置主密码"""
    master = MasterPassword.query.first()
    return jsonify({
        'exists': master is not None,
        'authenticated': 'master_password' in session
    })

@password_bp.route('/api/set-master', methods=['POST'])
def set_master_password():
    """设置主密码（首次使用）"""
    master = MasterPassword.query.first()
    if master:
        return jsonify({'error': '主密码已设置'}), 400
    
    data = request.json
    master_password = data.get('master_password')
    
    if not master_password or len(master_password) < 8:
        return jsonify({'error': '主密码至少8个字符'}), 400
    
    # 生成盐值和哈希
    salt = CryptoService.generate_salt()
    password_hash = CryptoService.hash_password(master_password, salt)
    
    # 保存到数据库
    master = MasterPassword(
        password_hash=password_hash,
        salt=salt
    )
    db.session.add(master)
    db.session.commit()
    
    # 保存到会话
    session['master_password'] = master_password
    session['master_salt'] = salt
    
    return jsonify({
        'success': True,
        'message': '主密码设置成功'
    })

@password_bp.route('/api/verify-master', methods=['POST'])
def verify_master_password():
    """验证主密码"""
    master = MasterPassword.query.first()
    if not master:
        return jsonify({'error': '请先设置主密码'}), 400
    
    data = request.json
    master_password = data.get('master_password')
    
    # 验证密码
    password_hash = CryptoService.hash_password(master_password, master.salt)
    
    if password_hash == master.password_hash:
        # 验证成功，保存到会话
        session['master_password'] = master_password
        session['master_salt'] = master.salt
        
        return jsonify({
            'success': True,
            'message': '验证成功'
        })
    else:
        return jsonify({'error': '主密码错误'}), 401

@password_bp.route('/api/logout', methods=['POST'])
def logout():
    """退出登录（清除会话）"""
    session.pop('master_password', None)
    session.pop('master_salt', None)
    
    return jsonify({
        'success': True,
        'message': '已退出'
    })

@password_bp.route('/api/passwords', methods=['GET'])
@master_password_required
def get_passwords():
    """获取密码列表（不包含密码内容）"""
    category = request.args.get('category')
    search = request.args.get('search')
    
    query = Password.query
    
    if category:
        query = query.filter_by(category=category)
    
    if search:
        query = query.filter(
            db.or_(
                Password.website.contains(search),
                Password.username.contains(search)
            )
        )
    
    passwords = query.order_by(Password.created_at.desc()).all()
    
    return jsonify({
        'passwords': [pwd.to_dict(include_password=False) for pwd in passwords]
    })

@password_bp.route('/api/passwords', methods=['POST'])
@master_password_required
def create_password():
    """创建新密码记录"""
    data = request.json
    
    # 加密密码
    plaintext_password = data['password']
    master_password = session['master_password']
    master_salt = session['master_salt']
    
    encrypted_password = CryptoService.encrypt(plaintext_password, master_password, master_salt)
    
    # 创建记录
    password = Password(
        website=data['website'],
        username=data['username'],
        password_encrypted=encrypted_password,
        category=data.get('category', '其他'),
        url=data.get('url', ''),
        notes=data.get('notes', '')
    )
    
    db.session.add(password)
    db.session.commit()
    
    return jsonify({
        'success': True,
        'password': password.to_dict(include_password=False)
    }), 201

@password_bp.route('/api/passwords/<int:password_id>', methods=['GET'])
@master_password_required
def get_password(password_id):
    """获取密码详情（包含解密的密码）"""
    password = Password.query.get_or_404(password_id)
    
    # 解密密码
    master_password = session['master_password']
    master_salt = session['master_salt']
    
    try:
        decrypted_password = CryptoService.decrypt(
            password.password_encrypted,
            master_password,
            master_salt
        )
    except ValueError as e:
        return jsonify({'error': str(e)}), 400
    
    data = password.to_dict(include_password=False)
    data['password'] = decrypted_password
    
    return jsonify(data)

@password_bp.route('/api/passwords/<int:password_id>', methods=['PUT'])
@master_password_required
def update_password(password_id):
    """更新密码记录"""
    password = Password.query.get_or_404(password_id)
    data = request.json
    
    # 更新字段
    if 'website' in data:
        password.website = data['website']
    if 'username' in data:
        password.username = data['username']
    if 'password' in data:
        # 重新加密密码
        master_password = session['master_password']
        master_salt = session['master_salt']
        password.password_encrypted = CryptoService.encrypt(
            data['password'],
            master_password,
            master_salt
        )
    if 'category' in data:
        password.category = data['category']
    if 'url' in data:
        password.url = data['url']
    if 'notes' in data:
        password.notes = data['notes']
    
    db.session.commit()
    
    return jsonify({
        'success': True,
        'password': password.to_dict(include_password=False)
    })

@password_bp.route('/api/passwords/<int:password_id>', methods=['DELETE'])
@master_password_required
def delete_password(password_id):
    """删除密码记录"""
    password = Password.query.get_or_404(password_id)
    db.session.delete(password)
    db.session.commit()
    
    return jsonify({
        'success': True,
        'message': '删除成功'
    })

@password_bp.route('/api/check-strength', methods=['POST'])
def check_password_strength():
    """检测密码强度"""
    data = request.json
    password = data.get('password', '')
    
    strength = CryptoService.check_password_strength(password)
    
    return jsonify(strength)

